import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.Method.GET
import static groovyx.net.http.Method.POST
import static groovyx.net.http.ContentType.TEXT
import static groovyx.net.http.ContentType.HTML

/**
 * 네이트 기사 베플을 파싱하고 저장하는 클래스
 * 
 * @author : TaeHo Kim (xissysnd@gmail.com)
 */
class Reply {
	static belongsTo = Article
	
	String content
	String username
	int countOfGood
	int countOfBad
	Date dateCreated
	Date dateViewed = new Date()

    static constraints = {
		content(blank:false)
		username(blacnk:false)
    }
	
	static mapping = {
		// dateCreated가 자동으로 갱신되는 것을 방지한다.
		autoTimestamp false
		content type: "text"
	}
	
	String toString() {
		"$username($countOfGood)"
	}
	
	
	/**
	 * 지정된 URL의 기사 베플들을 파싱
	 * 
	 * @param articleLinkUrl 네이트 뉴스 기사 페이지 URL 
	 * @return List of 베플 (보통 size 3개짜리, 빈 리스트일수도 있음)
	 */
	def static parseBestReplies(String articleLinkUrl) {
		def url = new URL(articleLinkUrl)
		def articleId = url.getPath().replace('/view/', '')
		
    	def htmlComment = new HTTPBuilder('http://newscomm.nate.com').request(GET,TEXT) { 
    		uri.path = '/ArticleComment/List'
			uri.query = [ artc_sq: articleId, ]
		}
        assert htmlComment instanceof Reader // response data is buffered in-memory
        def slurper = new XmlSlurper(new org.ccil.cowan.tagsoup.Parser())
        
    	def html = slurper.parse(htmlComment)
		def beple = html.'**'.find{ it.name() == 'div' && it.@class == 'cmt_best' }
		
		if(beple != null) {
			def listOfBeple = []
			beple = beple.dl
			
			for( reply in beple.list() ) {
				// 댓글 작성자 이름(username)은 싸이월드 링크가 있을 때와 없을 때가
				// 태그 구성 모습 다르기 때문에, 두 가지 방법으로 모두 접근해 줘야 할 필요가 있다.
				String username
				try {
					username = reply.'**'.find{ it.name() == 'a' && it.@class == 'nameui' }.text().trim()
				} catch(NullPointerException e) {
					username = reply.'**'.find{ it.name() == 'dt' && it.@class == 'beple' }.text().trim()
				}
				Date dateCreated = Date.parse('(MM.dd hh:mm)', reply.'**'.find{ it.name() == 'dd' && it.@class == 'usertxt' }.i.text())
				reply.'**'.find{ it.name() == 'dd' && it.@class == 'usertxt' }.i.replaceBody('')
				reply.'**'.findAll{ it.name() == 'br' }.each{ br -> br.replaceBody('<BR />') }
				String content = reply.'**'.find{ it.name() == 'dd' && it.@class == 'usertxt' }.text().trim()
				int countOfGood = reply.'**'.find{ it.name() == 'dd' && it.@class == 'n_good' }.text().trim() as int
				int countOfBad = reply.'**'.find{ it.name() == 'dd' && it.@class == 'n_bad' }.text().trim() as int
				
				def replyInstance = new Reply()
				replyInstance.username = username
				replyInstance.content = content
				replyInstance.dateCreated = dateCreated
				replyInstance.countOfGood = countOfGood
				replyInstance.countOfBad = countOfBad
				listOfBeple.add(replyInstance)
			}
			
			return listOfBeple
		}
		
		return null
	}
}
